package com.serie402.business.command.events;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.kiss.fw.command.AbstractCommand;
import com.kiss.fw.dto.AbstractDTO;
import com.kiss.fw.exceptions.CommandException;
import com.kiss.fw.exceptions.CommandInitializeException;
import com.kiss.fw.utils.Constants;
import com.serie402.business.dao.EventsDAO;
import com.serie402.business.dao.dto.EventDAODTO;
import com.serie402.common.bo.Event;
import com.serie402.common.dto.EventDTO;

public class ReadEventCmd extends AbstractCommand {
	private static final Logger logger = Logger.getLogger(ReadEventCmd.class);
	private static Map<Integer, Event> eventsCache = new HashMap<Integer, Event>();
	private static EventsDAO dao;
	
	@Override
	protected void initialize () throws CommandInitializeException {
		if(dao == null) {
			dao = EventsDAO.getInstance();
		}
		
		if(dao == null) {
			logger.error("DAO is null");
			throw Constants.Exceptions.COMMAND_INITIALIZE_EXCEPTION;
		}
	}
	
	@Override
	protected void authorize (AbstractDTO _dto) throws SecurityException {
	}
	
	@Override
	protected void preProcess (AbstractDTO _dto) throws CommandException {
		if(eventsCache.containsKey(getEventDTO(_dto).getEventId())) {
			// no need to perform process()
			setProcessCommand(false);
		}
	}
	
	@Override
	protected void process (AbstractDTO _dto) throws CommandException {
		EventDAODTO daoDto = new EventDAODTO();
		
		// TODO: should only be one event
		try {
			dao.read(daoDto);
		}
		catch(Exception _exception) {
			handleException(logger, "getEvents() - Error", _exception);
		}
		
		if(daoDto.getEvents() != null && daoDto.getEvents().size() > 0) {
			synchronized(eventsCache) {
				Event event = daoDto.getEvents().get(0);
				
				try {
					// TODO: Call Photo Album Command
//					event.setPhotoAlbum(MultimediaDelegate.getPhotoAlbum(event.getPhotoAlbum().getAlbumId()));
					eventsCache.put(event.getEventId(), event);
				}
				catch(Exception _exception) {
					handleException(logger, "getEvents() - Error occured updating cache", _exception);
				}
			}
		}
	}
	
	@Override
	protected void postProcess (AbstractDTO _dto) throws CommandException {
		EventDTO dto = getEventDTO(_dto);
		
		if(eventsCache.containsKey(dto.getEventId())) {
			// creating list that will hold event
			List<Event> events = new ArrayList<Event>(1);
			
			// adding event from the cache
			events.add(eventsCache.get(dto.getEventId()));
			
			// updating dto
			dto.setEvents(events);
		}
	}
	
	private EventDTO getEventDTO(AbstractDTO _dto) {
		return (EventDTO)_dto;
	}
}